package com.sys.service.impl;

import com.sys.dto.AbilityCurveData;
import com.sys.dto.DailyProgress;
import com.sys.dto.DomainCompletionStats;
import com.sys.dto.MultiDomainCurveData;
import com.sys.entity.BizAbilityScore;
import com.sys.entity.BizPlanItem;
import com.sys.entity.BizTask;
import com.sys.entity.BizTaskLog;
import com.sys.mapper.BizAbilityScoreMapper;
import com.sys.mapper.BizPlanItemMapper;
import com.sys.mapper.BizTaskLogMapper;
import com.sys.mapper.BizTaskMapper;
import com.sys.service.ProgressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ProgressServiceImpl implements ProgressService {

    @Autowired
    private BizTaskLogMapper taskLogMapper;

    @Autowired
    private BizAbilityScoreMapper abilityScoreMapper;

    @Autowired
    private BizPlanItemMapper planItemMapper;

    @Autowired
    private BizTaskMapper taskMapper;

    private static final String[] ALL_DOMAINS = {
        "social", "emotion", "selfcare", "communication", "cognition", "motor"
    };

    @Override
    public DailyProgress getDailyProgress(Long userId) {
        // 统计今天的计划项（而不是打卡记录）
        LocalDate today = LocalDate.now();
        List<BizPlanItem> planItems = planItemMapper.findByUserIdAndDate(userId, today);

        int total = planItems.size();
        // status = 1 表示已完成
        long completed = planItems.stream().filter(item -> item.getStatus() != null && item.getStatus() == 1).count();

        DailyProgress progress = new DailyProgress();
        progress.setTotal(total);
        progress.setCompleted((int) completed);
        progress.setRate(total > 0 ? (double) completed / total * 100 : 0);

        return progress;
    }

    @Override
    public AbilityCurveData getAbilityCurve(Long userId, String domain, String timeRange) {
        LocalDate endDate = LocalDate.now();
        LocalDate startDate = getStartDate(endDate, timeRange);

        List<BizAbilityScore> scores = abilityScoreMapper.findByUserIdAndDomainAndDateRange(userId, domain, startDate,
                endDate);

        AbilityCurveData curveData = new AbilityCurveData();
        curveData.setDates(scores.stream().map(s -> s.getScoreDate().format(DateTimeFormatter.ofPattern("MM-dd")))
                .collect(Collectors.toList()));
        curveData.setCompletionRates(
                scores.stream().map(s -> s.getScoreDecimal().doubleValue()).collect(Collectors.toList()));

        return curveData;
    }

    @Override
    public MultiDomainCurveData getMultiDomainCurve(Long userId, String startDate, String endDate) {
        LocalDate start = LocalDate.parse(startDate);
        LocalDate end = LocalDate.parse(endDate);

        // 获取所有领域的数据
        Map<String, List<Double>> domainDataMap = new HashMap<>();
        List<String> dates = new ArrayList<>();

        // 生成日期列表
        LocalDate currentDate = start;
        while (!currentDate.isAfter(end)) {
            dates.add(currentDate.format(DateTimeFormatter.ofPattern("MM/dd")));
            currentDate = currentDate.plusDays(1);
        }

        // 为每个领域获取数据
        for (String domain : ALL_DOMAINS) {
            List<BizAbilityScore> scores = abilityScoreMapper.findByUserIdAndDomainAndDateRange(
                userId, domain, start, end);
            
            // 创建日期到分数的映射
            Map<String, Double> dateScoreMap = scores.stream()
                .collect(Collectors.toMap(
                    s -> s.getScoreDate().format(DateTimeFormatter.ofPattern("MM/dd")),
                    s -> s.getScoreDecimal().doubleValue(),
                    (v1, v2) -> v1 // 如果有重复日期，保留第一个
                ));

            // 填充完整的日期序列，缺失的日期使用前一天的值或默认值
            List<Double> ratesList = new ArrayList<>();
            Double lastValue = 70.0; // 默认起始值
            for (String date : dates) {
                Double value = dateScoreMap.get(date);
                if (value != null) {
                    ratesList.add(value); // score_decimal 已经是 0-100 的值，不需要再乘以100
                    lastValue = value;
                } else {
                    ratesList.add(lastValue);
                }
            }
            
            domainDataMap.put(domain, ratesList);
        }

        MultiDomainCurveData curveData = new MultiDomainCurveData();
        curveData.setDates(dates);
        curveData.setDomainData(domainDataMap);
        
        return curveData;
    }

    @Override
    public List<DomainCompletionStats> getDomainCompletionStats(Long userId, String startDate, String endDate) {
        LocalDate start = LocalDate.parse(startDate);
        LocalDate end = LocalDate.parse(endDate);
        
        List<DomainCompletionStats> statsList = new ArrayList<>();
        
        // 获取该时间段内的所有计划项
        List<BizPlanItem> planItems = planItemMapper.findByUserIdAndDateRange(userId, start, end);
        
        for (String domain : ALL_DOMAINS) {
            // 获取该领域的所有任务ID
            List<BizTask> domainTasks = taskMapper.findByDomain(domain);
            Set<Long> domainTaskIds = domainTasks.stream()
                .map(BizTask::getId)
                .collect(Collectors.toSet());
            
            // 筛选出属于当前领域的计划项
            List<BizPlanItem> domainPlanItems = planItems.stream()
                .filter(item -> domainTaskIds.contains(item.getTaskId()))
                .collect(Collectors.toList());
            
            int total = domainPlanItems.size();
            long completed = domainPlanItems.stream()
                .filter(item -> item.getStatus() != null && item.getStatus() == 1)
                .count();
            
            DomainCompletionStats stats = new DomainCompletionStats();
            stats.setDomain(domain);
            stats.setDomainName(getDomainName(domain));
            stats.setTotal(total);
            stats.setCompleted((int) completed);
            stats.setCompletionRate(total > 0 ? (double) completed / total * 100 : 0.0);
            
            statsList.add(stats);
        }
        
        return statsList;
    }

    @Override
    public List<Map<String, Object>> getHistory(Long userId, String startDate, String endDate) {
        LocalDate start = LocalDate.parse(startDate);
        LocalDate end = LocalDate.parse(endDate);
        
        LocalDateTime startTime = start.atStartOfDay();
        LocalDateTime endTime = end.atTime(23, 59, 59);

        List<BizTaskLog> logs = taskLogMapper.findByUserIdAndDateRange(userId, startTime, endTime);
        
        // 组装返回数据，包含任务详情
        List<Map<String, Object>> result = new ArrayList<>();
        for (BizTaskLog log : logs) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", log.getId());
            item.put("taskId", log.getTaskId());
            item.put("status", log.getStatus());
            item.put("score", log.getScore());
            item.put("remarks", log.getRemarks());
            item.put("photosCount", log.getPhotosCount());
            item.put("loggedAt", log.getLoggedAt());
            
            // 查询任务详情
            BizTask task = taskMapper.selectById(log.getTaskId());
            if (task != null) {
                item.put("taskTitle", task.getTitle());
                item.put("taskDescription", task.getDescription());
                item.put("taskDomain", task.getDomain());
            }
            
            result.add(item);
        }
        
        return result;
    }

    private LocalDate getStartDate(LocalDate endDate, String timeRange) {
        switch (timeRange) {
            case "1week":
            case "1w":
                return endDate.minusWeeks(1);
            case "1month":
            case "1m":
                return endDate.minusMonths(1);
            case "3months":
            case "3m":
                return endDate.minusMonths(3);
            case "6months":
            case "6m":
                return endDate.minusMonths(6);
            case "1year":
            case "1y":
                return endDate.minusYears(1);
            default:
                return endDate.minusDays(7);
        }
    }

    private String getDomainName(String domain) {
        switch (domain) {
            case "social":
                return "社交能力";
            case "emotion":
                return "情绪管理";
            case "selfcare":
                return "生活自理";
            case "communication":
                return "沟通交流";
            case "cognition":
                return "认知能力";
            case "motor":
                return "行为干预";
            default:
                return domain;
        }
    }
}